package model.eval;

import j_util.Utiles;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Establece la estructura general que debe adoptar un test;
 *
 * @author Jose Martin Rozanec;
 */
public class Test implements Serializable {
    private List<TestExcercise> excercises;
    private int minutes;
    private int pointer;

    /**
     * Constructor;
     */
    public Test() {
        excercises = new ArrayList<TestExcercise>();
    }

    /**
     * Permite obtener los ejercicios;
     *
     * @return List<TestExcercise>;
     */
    public List<TestExcercise> getExcercises() {
        return excercises;
    }

    /**
     * Permite setear los ejercicios;
     *
     * @param excercises - List<TestExcercise>;
     */
    public void setExcercises(List<TestExcercise> excercises) {
        this.excercises = excercises;
    }

    /**
     * Permite agregar un ejercicio;
     *
     * @param excercise - TestExcercise;
     */
    public void addExcercise(TestExcercise excercise) {
        excercises.add(excercise);
        pointer = excercises.size() - 1;
    }

    /**
     * Permite obtener la cantidad de minutos que dura el test;
     *
     * @return int minutos;
     */
    public int getMinutes() {
        return minutes;
    }

    /**
     * Permite setear la cantidad de minutos que durara el test;
     *
     * @param minutes - duracion del test;
     */
    public void setMinutes(int minutes) {
        this.minutes = minutes;
    }

    /**
     * Returns next excercise. If reaches the end, returns the first excercise, in a circular shift fashion;
     *
     * @return
     */
    public TestExcercise next() {
        pointer++;
        if (pointer >= excercises.size()) {
            pointer = 0;
        }
        System.out.println("Test:- pointer: " + pointer + "; exercises: " + excercises.size());//todo delete
        return excercises.get(pointer);
    }

    /**
     * Returns previous excercise. If reaches the first element and you ask for the previous one,
     * returns the last excercise, in a circular shift fashion;
     *
     * @return TestExcercise;
     */
    public TestExcercise previous() {
        pointer--;
        if (pointer < 0) {
            pointer = excercises.size() - 1;
        }
        return excercises.get(pointer);
    }

    /**
     * Devuelve el total de ejercicios en el test;
     *
     * @return int;
     */
    public int getTotalExcercises() {
        return excercises.size();
    }

    /**
     * Devuelve el numero de ejercicio actual;
     *
     * @return int;
     */
    public int getCurrentExerciseNumber() {
        return pointer + 1;
    }

    /**
     * Devuelve el maximo puntaje que se puede obtener con la evaluacion;
     *
     * @return int;
     */
    public int getTotalScore() {
        int totalScore = 0;
        for (int j = 0; j < excercises.size(); j++) {
            totalScore = totalScore + excercises.get(j).getCorrectScore();
        }
        return totalScore;
    }

    /**
     * Permite obtener el TestExcercise actual;
     *
     * @return TestExcercise;
     */
    public TestExcercise getCurrent() {
        return excercises.get(pointer);
    }

    /**
     * Permite eliminar el ejercicio actual;
     */
    public void deleteCurrentExcercise() {
        excercises.remove(pointer);
    }

    /**
     * Resetea la evaluacion eliminando todos los ejercicios;
     */
    public void reset() {
        excercises = new ArrayList<TestExcercise>();
        minutes = 0;
        pointer = 0;
    }

    /**
     * Permite obtener el puntaje logrado a partir de la resolucion de los ejercicios;
     *
     * @return int score;
     */
    public int getAchievedScore() {
        int achievedScore = 0;
        for (int j = 0; j < excercises.size(); j++) {
            achievedScore += excercises.get(j).getAchievedScore();
        }
        return achievedScore;
    }

    /**
     * Devuelve el porcentaje de ejercicios bien resueltos;
     *
     * @return double porcentaje;
     */
    public double getAchievedPercentage() {
        return (double) getAchievedScore() / (double) getTotalScore();
    }

    /**
     * Representacion en String del test;
     *
     * @return String;
     */
    public String toString() {
        StringBuffer buffer = new StringBuffer();
        if (excercises.size() == 0) {
            return "";
        }
        buffer.append(Utiles.getRomanNumberRepresentation(1) + "- " + excercises.get(0).toString());
        for (int j = 1; j < excercises.size(); j++) {
            buffer.append("\n\n" + Utiles.getRomanNumberRepresentation(j + 1) + "- " + excercises.get(j).toString());
        }
        return buffer.toString();
    }

    /**
     * Devuelve la representacion en String de la solucion del alumno;
     *
     * @return String;
     */
    public String getStudentSolutionString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(Utiles.getRomanNumberRepresentation(1) + "- " + excercises.get(0).getStudentSolutionString());
        for (int j = 1; j < excercises.size(); j++) {
            buffer.append("\n\n" + Utiles.getRomanNumberRepresentation(j + 1) + "- " +
                    excercises.get(j).getStudentSolutionString());
        }
        return buffer.toString();
    }

    /**
     * Returns the percentage of exercises labeled as resolved;
     * @return percentage - double;
     */
    public int getResolvedTestsPercentage(){
        double resolved=0;
        for(int j=0;j<excercises.size();j++){
            if(excercises.get(j).isResolved()){
                resolved++;
            }
        }
        return (int)((resolved/((double)getTotalExcercises()))*100);

    }
}
